<?php
/**
 * Publication class.
 *
 * 
 * 
 * Responsible for the creation, reading, updating, deletion, and management of the publications.

 * 
 * PHP version 5
 *
 * LICENSE: This source file is subject to version 3.01 of the PHP license
 * that is available through the world-wide-web at the following URI:
 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
 * the PHP License and are unable to obtain it through the web, please
 * send a note to license@php.net so we can mail you a copy immediately.
 *
 * @package    Subbear Subscription Management
 * @author     Shawn Wernig ( shawn@eggplantstudios.ca )
 * @copyright  2013 
 * @license    http://www.eggplantstudios.ca
 * @version    2.0
 */

class Publication {

    public $publication_id;
    
    public $datestamp;
           
    public $name;
    public $setting_email;
    private $password;
    public $username;
    public $week_origin;
    
    public $setting_records_per_page;
    public $setting_local_locations;
    public $setting_province;
    public $setting_country;
    public $setting_expiring_tolerance;
    public $setting_expired_tolerance;
    public $setting_sort_order;
    public $setting_sort_order_array;

    public $publication_day;
    public $table_name;
   
    private static $publication_table_name = "publication";
    
    public function __construct() {
    }
    
    
    
     /**
     * Gets an attribute
     *
     * @return void
     * @param $object = the object to display; Typically a class, or array.
     * @author epstudios
     */      
    public function attr($attr) {
        echo ucwords( htmlspecialchars($this->$attr) );
    }
    public function get_attr($attr) {
        return  $this->$attr;
    }
    
    /**
     * Gets the full table name for this subscritpion
     *
     * @return string
     * @author epstudios
     */
    public static function get_tablename() {
        return htmlspecialchars(self::$publication_table_name); 
        
    }    
    
    
    
    
    
    /**
     * Gets ta publication by id.
     *
     * @return string
     * @author epstudios
     */
    public static function find_by_id($publication_id) {
        $objects = self::find_by_sql("SELECT * FROM " . self::get_tablename() . " WHERE publication_id=$publication_id LIMIT 1" );
        return ( isset($objects) && is_array($objects) ) ? $objects[0] : false;
    }   
    
   
   
    /**
     * Gets all publications.
     *
     * @return string
     * @author epstudios
     */
    public static function get_publications() {
        $objects = self::find_by_sql("SELECT * FROM "  . self::get_tablename() );
        return ( $objects ) ? $objects : false;
    }
    
     /**
     * Gets gets admin email for a given publication
     *
     * @return string
     * @author epstudios
     */
    public static function get_admin_email($pub_id) {
        $objects = self::find_by_sql("SELECT setting_email FROM "  . self::get_tablename() . " WHERE publication_id={$pub_id} LIMIT 1" );
        if ($objects) {
                return $objects[0]->setting_email;
        } else {
            return EMAIL;
        }
   }
    
    
    
    
    
    
     
    
    
    
    
    
    public function update_password($password) {
        if ( isset($password ) && $password != '') {
            global $db;
            global $session;
            $sql =  "UPDATE ". self::get_tablename()." ";
            $sql .= "SET password='". $db->hash_pass($password)."' ";
            $sql .= "WHERE publication_id={$this->publication_id}";
                
            if ( $this->update_by_sql($sql) ) {
                $session->add_message('Password change successful. Please don\'t forget it!');
                return true;
            }
        }
        return false;
    }
    
    public static function login($array) {
        global $db;
        $sql =  "SELECT publication_id FROM ".self::get_tablename()." WHERE username='{$array['username']}' AND password='" . $db->hash_pass($array['password'])."' LIMIT 1";
        $result = $db->query( $sql );
        $result = $db->fetch_array($result);
        return ($result) ? $result['publication_id'] : false;
    }
    
    
    /**
     * 
     * 
     * This function gets posted data, validates and saves it to the given publication.
     */
    public static function update_publication() {
        global $session;
        
        if ( $_POST['password1'] == $_POST['password2']) {
            
            // Create a new instance.
            $publication = Publication::instantiate($_POST);
            
            
            $pub_id = $publication->save();
            
            
            if ( $pub_id ) {
                // Update passwords.
                $publication->update_password($_POST['password1']);
                
                header('Location: index.php?page=publication'); exit;
            } else { $session->add_message('ERROR: Could not save this publication.'); return false; }
    
        } else { $session->add_message('ERROR: Your passwords did not match.'); return false;}
    }
    
    /**
     * SAVES this instance to the databse if successful.
     * 
     * 
     * @access private 
     * @return boolean
     * 
     */
    public function save(){
        global $session;
        $scrub_us = false; 
        if ( $this->_validate() ) {
            // Figure out if we're changing crucial settings that affect the subs
            if ( $this->is_new() === false ) {
                $old_pub = self::find_by_id($this->publication_id);
                if ( ($old_pub->setting_expiring_tolerance != $this->setting_expiring_tolerance) || ($old_pub->publication_day != $this->publication_day)  ) {
                    // We need to Refresh all subs again.
                    $scrub_us = true;
                }
            }
            
            $this->publication_id = $this->_update_self();
            
            if ( $this->publication_id  ){
                if ( $scrub_us ) Subscription::scrub_subs($this->publication_id);
                $session->add_message("SUCCESS: {$this->name} has been successfully saved.");
                return $this->publication_id;
            }
            $session->add_message("ERROR: {$this->name} could not be saved.");
            return false;
        }
        
    }


    public function is_new(){
        return ( isset($this->publication_id) && !empty( $this->publication_id ) && !is_null( $this->publication_id ) ) ? false : true ;
    }
        
    /**
     * VALIDATES the class.
     * 
     * 
     * @access private 
     * @return boolean
     * 
     */
    private function _validate(){
        $validator = new Validator;
        global $session;
        
        // Escape all!
        $validator->escape_class($this);
        
        // Check email.
        if ( !$validator->is_email($this->setting_email) ) {
             $session->add_message("ERROR: {$this->setting_email} is not a valid email. Reports and notifications will be emailed to this address, please specify a valid email.");
             return false;
        }
        
        $this->setting_records_per_page = ( $this->setting_records_per_page > 500 ) ? 500 : $this->setting_records_per_page;
        $this->setting_local_locations = $validator->prepare_csv( $this->setting_local_locations );
        $this->week_origin = date( 'Y-m-d', strtotime( $this->publication_day . ' January 2007')); //OUR ORIGIN WEEK IS SET AT THE FIRST WEEK OF 2007, BECAUSE 1 - MONDAY, 2 - TUESDAY, ETC.
        if( self::is_new() ) $this->setting_sort_order = 'postal_code,rr,box,street,street_address,apt';
        
        return true;
    }
    
         
    /**
     * UPDATES the database.
     * 
     * 
     * @access private 
     * @return id
     * 
     */
    private function _update_self() {
        global $db;
        global $session;

        if( $this->is_new() === false ) {
            $sql =  "UPDATE ". self::get_tablename()." ";
            $sql .= "SET name='{$this->name}', 
                        week_origin='{$this->week_origin}', 
                        publication_day={$this->publication_day},
                        setting_email='{$this->setting_email}', 
                        setting_local_locations='{$this->setting_local_locations}', 
                        setting_province='{$this->setting_province}',   
                        setting_records_per_page={$this->setting_records_per_page}, 
                        setting_country='{$this->setting_country}', 
                        setting_sort_order='{$this->setting_sort_order}', 
                        setting_expiring_tolerance={$this->setting_expiring_tolerance},
                        setting_expired_tolerance={$this->setting_expired_tolerance} ";
                        
            $sql .= "WHERE publication_id={$this->publication_id}";
        } else {
            $sql =  "INSERT INTO ".self::get_tablename()." ";
            $sql .= "( datestamp, name, setting_email, username, week_origin, setting_records_per_page, setting_local_locations, setting_province, setting_country, setting_expiring_tolerance, setting_expired_tolerance, setting_sort_order, publication_day, table_name, password) ";
            $sql .= "VALUES (
            '".date( 'Y-m-d H:i:s', time() )."', '{$this->name}', '{$this->setting_email}', '{$this->username}', 
                    {$this->week_origin}, {$this->setting_records_per_page}, '{$this->setting_local_locations}', '{$this->setting_province}', '{$this->setting_country}', {$this->setting_expiring_tolerance}, {$this->setting_expired_tolerance}, '{$this->setting_sort_order}', {$this->publication_day}, '{$this->table_name}', '".$db->hash_pass($this->password)."')";
            $this->create_tables( $this->table_name );
        }
        
        $result = $db->query( $sql );
        
        if  ( $result ) {
                
            if ( $this->is_new() != true ) {
                return $this->publication_id;
            } else {
                
                $sql =  "SELECT LAST_INSERT_ID() AS new_pub_id FROM ".self::get_tablename();
                $result_set = $db->query( $sql );
                $row = $db->fetch_array($result_set);
                $this->publication_id = $row['new_pub_id'];
                $this->update_password($_POST['password1']);
                
                header('Location: index.php'); exit;
            }
        }
        return false;      
         
    }



    /* --------------------------------------- SQL --------------------------------------- */
    

    
    public static function find_by_sql ( $sql="") {
        global $db;
        $result_set = $db->query( $sql );
        
        $object_array = array();
        while ($row = $db->fetch_array($result_set)) {
            $object_array[] = self::instantiate($row);
        }
        return $object_array;
    }
    
    public static function update_by_sql ( $sql="") {
        global $db;
        $result_set = $db->query( $sql );
        if ($db->affected_rows() == 1) return TRUE;
        return FALSE;
    }

    public static function instantiate ($record) {
        $object = new self;
        foreach ( $record as $key=>$value ) {
            if ( $object->has_attribute($key)) {
                
                switch( $key ) {
                    case 'setting_sort_order':
                        if( is_array($value) ) {
                            $object->$key= implode(',', $value);
                        } else {
                            $object->$key = $value;
                        }
                        break;
                    default: $object->$key = $value; break;
                }
                
            }
        }
        
        $object->setting_sort_order_array = explode(',', $object->setting_sort_order );
        return $object;
    }
    
    private function has_attribute ( $key ) {
        $object_vars = get_object_vars($this);
        return array_key_exists($key, $object_vars);
        
    }
    
    private function create_tables( $table_name ) {
        global $db;
        $db->query("
                 CREATE TABLE IF NOT EXISTS {$table_name}_report (
                  `report_id` int(11) unsigned NOT NULL auto_increment,
                  `datestamp` datetime DEFAULT NULL,
                  `url` varchar(256) DEFAULT NULL,
                  `file_type` char(4) NOT NULL DEFAULT '',
                  `category` int(24) unsigned NOT NULL,
                  `filename` varchar(48) DEFAULT NULL,
                   PRIMARY KEY (`report_id`)
                ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1");
                

            $db->query("
                  CREATE TABLE IF NOT EXISTS {$table_name}_user (
                  `user_id` int(11) unsigned NOT NULL auto_increment,
                  `user_datestamp` datetime DEFAULT NULL,
                  `firstname` varchar(48) DEFAULT NULL,
                  `lastname` varchar(48) DEFAULT NULL,
                  `displayname` varchar(96) DEFAULT '',
                  `phone` varchar(14) DEFAULT NULL,
                  `email` varchar(48) DEFAULT NULL,
                  `apt` varchar(10) DEFAULT NULL,
                  `box` varchar(10) DEFAULT NULL,
                  `rr` varchar(10) DEFAULT NULL,
                  `street_address` char(96) DEFAULT NULL,
                  `street` char(96) DEFAULT NULL,
                  `city` varchar(48) DEFAULT NULL,
                  `postal_code` varchar(7) DEFAULT NULL,
                  `province` varchar(2) DEFAULT NULL,
                  `country` varchar(48) DEFAULT NULL,
                  PRIMARY KEY (`user_id`)
                ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1");
                


            $db->query("
                 CREATE TABLE IF NOT EXISTS {$table_name}_subscription (
                  `subscription_id` int(11) unsigned NOT NULL auto_increment,
                  `subscription_datestamp` datetime DEFAULT NULL,
                  `user_id` int(11) unsigned DEFAULT NULL,
                  `publication_id` int(11) unsigned DEFAULT NULL,
                  `start_week` int(11) unsigned DEFAULT NULL,
                  `trashed` tinyint(1) NOT NULL DEFAULT '0',
                  `status` varchar(10) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`subscription_id`),
                  KEY `publication_id` (`publication_id`),
                  KEY `user_id` (`user_id`),
                  CONSTRAINT `{$table_name}_subscription_ibfk_2` FOREIGN KEY (`publication_id`) REFERENCES `publication` (`publication_id`) ON DELETE SET NULL ON UPDATE SET NULL,
                  CONSTRAINT `{$table_name}_subscription_ibfk_3` FOREIGN KEY (`user_id`) REFERENCES `{$table_name}_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
                ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1");

                
               $db->query("
            CREATE TABLE IF NOT EXISTS {$table_name}_allowance (
              `allowance_id` int(11) unsigned NOT NULL auto_increment,
              `datestamp` datetime DEFAULT NULL,
              `queue` int(11) unsigned NOT NULL DEFAULT '0',
              `subscription_id` int(11) unsigned DEFAULT NULL,
              `total_duration` int(11) unsigned DEFAULT NULL,
              `type` varchar(5) NOT NULL DEFAULT 'add',
              PRIMARY KEY (`allowance_id`),
              KEY `subscription_id` (`subscription_id`),
              CONSTRAINT `{$table_name}allowance_ibfk_1` FOREIGN KEY (`subscription_id`) REFERENCES `{$table_name}_subscription` (`subscription_id`) ON DELETE SET NULL ON UPDATE SET NULL
                ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1");
    }
    
}
?>